﻿using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace PlayListSet.Comm
{
    public delegate void TimeCodePlaybackState(PlaybackState playbackState);
    public delegate void TimeCodeChanged(TimeSpan currentTime);

    internal class TimeCodePlayContorl : System.ComponentModel.INotifyPropertyChanged
    {
        private System.Timers.Timer timer;

        private NAudio.Wave.WaveOut waveOut;
        private AudioFileReader audioFileReader;
        private PlaybackState playbackState= PlaybackState.Stopped;
        public event TimeCodePlaybackState OnTimeCodePlaybackState;
        public event TimeCodeChanged TimeCodeChanged;
        public event PropertyChangedEventHandler PropertyChanged;

        private TimeSpan currentTime;
        public TimeSpan CurrentTime
        {
           private set { currentTime = value; }
           get { return currentTime; }
        }
        public TimeSpan GetCurrentTime()
        {
            return audioFileReader.CurrentTime;
        }
        public PlaybackState PlaybackState
        {
            set
            {
                playbackState = value; 
                OnTimeCodePlaybackState?.Invoke(value);
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PlaybackState"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PlaybackStateInt"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PlaybackStateStr"));

            }
            get { return playbackState; }
        }
        public string PlaybackStateStr
        {
            get
            {
                switch (PlaybackState)
                {
                    case PlaybackState.Stopped: return "停止";
                    case PlaybackState.Playing: return "正在播放中";
                    case PlaybackState.Paused: return "暂停";
                    default: return "停止";
                }
            }
        }
        public int PlaybackStateInt
        {

            get
            {
                switch (PlaybackState)
                {
                    case PlaybackState.Stopped: return 0;
                    case PlaybackState.Playing: return 1;
                    case PlaybackState.Paused: return 2;
                    default: return 0;
                }
            }
        }
        private Dispatcher dispatcher;
        public TimeCodePlayContorl(Dispatcher dispatcher) 
        {
            this.dispatcher = dispatcher;
            var di = Entity.AudioInfo.GetAudioOutIndex(AppControl.Instance.AppConfig.LTCAudioDevice);
            waveOut = new NAudio.Wave.WaveOut( );
            if (di >= 0)
            {
                waveOut.DeviceNumber = di;
            }
           
            var ltcFile = System.IO.Path.Combine(
                    System.AppDomain.CurrentDomain.BaseDirectory,
                    AppControl.Instance.AppConfig.LTCMp3);
            if (!System.IO.File.Exists(ltcFile))
            {
                throw new Exception("LTC音频文件不存在，"+ ltcFile);
            }
            audioFileReader = new NAudio.Wave.AudioFileReader(
                ltcFile
                );
            waveOut.Init(audioFileReader);
            audioFileReader.Volume= AppControl.Instance.AppConfig.LTCEnable?1:0;
            waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
            timer = new System.Timers.Timer(30);
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if(PlaybackState== PlaybackState.Playing)
            {
                CurrentTime = audioFileReader.CurrentTime;
                TimeCodeChanged?.Invoke(CurrentTime);
            }
        }
      
        private void WaveOut_PlaybackStopped(object sender, StoppedEventArgs e)
        {
            PlaybackState = PlaybackState.Stopped;
            //Console.WriteLine("WaveOut_PlaybackStopped");
        }

        public void Play()
        {
            if (Thread.CurrentThread != dispatcher.Thread)
            {
                dispatcher.Invoke(Play);
                return;
            }
            waveOut.Play();
            PlaybackState = waveOut.PlaybackState;

        }
        public void Pause()
        {
            if (Thread.CurrentThread != dispatcher.Thread)
            {
                dispatcher.Invoke(Pause);
                return;
            }
            waveOut.Pause();
            PlaybackState = waveOut.PlaybackState;
        }
        public void Stop()
        {
            if (Thread.CurrentThread != dispatcher.Thread)
            {
                dispatcher.Invoke(Stop);
                return;
            }
            waveOut.Stop();
            PlaybackState = waveOut.PlaybackState;
            Seek(TimeSpan.Zero);
            TimeCodeChanged?.Invoke(CurrentTime);
        }
        public void Seek(TimeSpan duration)
        {
            if (Thread.CurrentThread != dispatcher.Thread)
            {
                dispatcher.Invoke(() => {
                    Seek(duration);
                });
                return;
            }
            CurrentTime = duration;
            audioFileReader.CurrentTime = duration;

        }
        ~TimeCodePlayContorl()
        {
            Stop();
            timer.Stop();
        }
    }
}
